package com.exp.security.config;

import com.exp.security.config.captcha.CaptchaAuthenticationFilter;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 *
 * @author zhangxj
 * @date 2025/1/2
 * @Description
 */
@Configuration
public class WebSecurityConfig {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                // 开启授权保护
                .authorizeHttpRequests(authorize -> authorize
                        // 验证码请求不需要认证
                        .requestMatchers("/captcha").permitAll()
                        // 任务请求都要求
                        .anyRequest()
                        // 已认证用户自动授权
                        .authenticated()
                )
                .formLogin(
                        // 自定义登录页面
                        form -> form.loginPage("/login")
                                // 登录页面不需要认证
                                .permitAll()
                                // 自定义表单登录参数
//                                .usernameParameter("myusername")
//                                .passwordParameter("mypassword")
                                // 登录失败跳转地址,默认是/login?error
                                .failureUrl("/login?failure")
                                // 认证成功后的处理
                                .successHandler(new MyAuthenticationSuccessHandler())
                                // 认证失败后的处理
                                .failureHandler(new MyAuthenticationFailureHandler())
                )
                .httpBasic(Customizer.withDefaults());

        // 自定义登出处理
        http.logout( logout -> logout.logoutSuccessHandler(new MyLogoutSuccessHandler()) );
        // 自定义认证失败处理
        http.exceptionHandling(exception -> exception
                // 请求未认证的处理
                .authenticationEntryPoint(new MyAuthenticationEntryPoint())
        );

        // 会话管理配置
        http.sessionManagement(session ->
                // 同一个账号在同一时间最多在一个客户端登陆
                session.maximumSessions(1)
                        .expiredSessionStrategy(new MySessionInformationExpiredStrategy())
        );

        // 添加验证码校验过滤器
        http.addFilterBefore(new CaptchaAuthenticationFilter(new MyAuthenticationFailureHandler(), stringRedisTemplate), UsernamePasswordAuthenticationFilter.class);

        // 关闭CSRF保护
        http.csrf(AbstractHttpConfigurer::disable);

        // 跨域请求
        http.cors(Customizer.withDefaults());
        return http.build();
    }
}
